using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO.Ports;
using System.IO;
using System.Threading;
using System;
using System.Text;

public enum KeyType { 圆形按钮, 方形按钮, 前, 后, 左, 右 }//按钮    

public class SerialPortManagr : MonoBehaviour {    
    public string portName = "COM5";
    public int baudRate = 9600;
    public int dataBits = 8;
    public StopBits stopBits = StopBits.None;    
    public Parity parity = Parity.None;
    private static SerialPortManagr _instance;
    SerialPort serialPort;
    Thread thread_reviceData;//数据接收线程
    List<byte> list_data = new List<byte>();
    Queue<string> queue_data = new Queue<string>();//消息队列
    char[] char_data;
    string str_data;
    public bool[] KeyClickState = new bool[6];//手柄按钮点击的状态
    public KeyType keyType;
    public int count_key;

    public static SerialPortManagr Instance
    {
        get
        {            
            return _instance;
        }
    }

    void Awake()
    {
        if (_instance == null)
        {
            DontDestroyOnLoad(this);
            _instance = this;
        }
        else
        {
            Destroy(this);
        }
    }

    void Start()
    {
        OpenPort();
        thread_reviceData = new Thread(new ThreadStart(DataReviceThread));
        thread_reviceData.Start();
    }

    void Update()
    {        
        if (queue_data.Count > 0)
        {
            queue_data.Dequeue();//清除第一条队列
            switch (str_data)
            {
                case "255142542515"://圆形
                    KeyClickState[0] = true;
                    //print("圆形按钮");
                    break;
                case "255152542504"://方形
                    KeyClickState[1] = true;
                    //print("方形按钮");
                    break;
                case "255182542479"://前
                    KeyClickState[2] = true;
                    //print("前");
                    break;
                case "255172542486"://后
                    KeyClickState[3] = true;
                    //print("后");
                    break;
                case "255162542497"://左
                    KeyClickState[4] = true;
                    //print("左");
                    break;
                case "255112542540"://右
                    KeyClickState[5] = true;
                    //print("右");
                    break;
                default:
                    break;
            }
        }
        else
        {
            for (int i = 0; i < KeyClickState.Length; i++)
            {
                KeyClickState[i] = false;//重置所有的按钮状态
            }
        }
    }

    void OpenPort()
    {
        print("打开串口");
        try
        {
            serialPort = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
            serialPort.Open();
        }
        catch (System.Exception ex)
        {
            print("串口打开异常:"+ex);
        }
        
    }

    void ClosePort()
    {
        print("关闭串口");
        try
        {
            serialPort.Close();
            thread_reviceData.Abort();
        }
        catch (System.Exception ex)
        {
            print("串口关闭异常：" + ex);
        }        
    }

    void DataReviceThread()
    {
        byte[] bytes_read = new byte[1024];
        int count = 0;
        while (serialPort != null && serialPort.IsOpen)
        {
            try
            {
                count = serialPort.Read(bytes_read, 0, bytes_read.Length);//读取消息并获取字节数
                if (count == 0)
                    continue;
                else
                {                    
                    //print("字节数量:" + count);
                    //if (count == 6)
                    //{
                    //    StringBuilder stringBuilder = new StringBuilder();
                    //    for (int i = 0; i < count; i++)
                    //    {
                    //        stringBuilder.Append(Convert.ToString(bytes_read[i]));
                    //    }
                    //    str_data = stringBuilder.ToString();
                    //    //print(str_data);
                    //    queue_data.Enqueue(str_data);//将接收的消息放入队列                        
                    //}                       
                }
            }
            catch (Exception ex)
            {
                print("串口读取数据异常：" + ex);
            }
            Thread.Sleep(10);
        }

        //while (serialPort != null && serialPort.IsOpen)
        //{
        //    Thread.Sleep(1);
        //    try
        //    {
        //        byte byte_read = Convert.ToByte(serialPort.ReadByte());
        //        serialPort.DiscardInBuffer();//清楚串口数据
        //        list_data.Add(byte_read);//将接收的字节放入列表中
        //        PrintData();
        //    }
        //    catch (Exception ex)
        //    {
        //        print("串口读取数据异常：" + ex);
        //        list_data.Clear();
        //    }            
        //}
    }//数据接收的多线程

    void PrintData()
    {
        for (int i = 0; i < list_data.Count; i++)
        {
            char_data[i] = (char)(list_data[i]);
            str_data = new string(char_data);
        }
        print(str_data);
    }//打印数据

    public bool InputKeyClickDown(KeyType keyType)
    {        
        return KeyClickState[(int)keyType];
    }//如果按下按钮，由于update刷新bool为false，所以只返回一次true

    public bool anyKeyDown()
    {
        count_key = Enum.GetNames(keyType.GetType()).Length;//获取枚举的长度
        for (int i = 0; i < count_key; i++)
        {
            if (KeyClickState[i])
            {
                return KeyClickState[i];
            }            
        }
        return false;
    }//如果按下了任意的按键

    void OnApplicationQuit()
    {        
        ClosePort();
    }

    byte[] MessageHandling(byte[] _message)
    {
        using(MemoryStream ms = new MemoryStream())
        {
            using (BinaryWriter bw = new BinaryWriter(ms))
            {
                bw.Write(ms.Length);
                bw.Write(_message);
                byte[] message = new byte[ms.Length];
                Buffer.BlockCopy(ms.GetBuffer(),0,message,0,message.Length);
                return message;
            }
        }        
    }

    #region 发送数据
    public void WriteData(string dataStr)
    {
        if (sp.IsOpen)
        {
            sp.Write(dataStr);
        }
    }
    void OnGUI()
    {
        message = GUILayout.TextField(message, GUILayout.Width(200), GUILayout.Height(50));
        if (GUILayout.Button("发送输入信息到串口对象", GUILayout.Width(200), GUILayout.Height(50)))
        {
            WriteData(message);
        }
        string test = "AA BB 01 12345 01AB 0@ab 发送";//测试字符串
        if (GUILayout.Button("发送默认信息到串口对象", GUILayout.Width(200), GUILayout.Height(50)))
        {
            WriteData(test);
        }
    }//OnGUI方法调试串口发送指令，如果不需要调试时，则可以自行注释OnGUI方法
    #endregion
}
